/*
 *
 * SimplePCR1000 (Qt4) Version 1.x
 * Copyright (C) 2011  Tyler H. Jones (me@tylerjones.me)
 * http://www.thebasementserver.com/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */


#include "radiocontroller.h"

RadioController::RadioController() //Constructor
{
    //COM = new Common();
}

RadioController::~RadioController() //Deconstructor
{
    delete port;
    port = NULL;
}

void RadioController::Open(QString portname) {
    //modify the port settings on your own
    #ifdef Q_WS_X11
            port = new QextSerialPort(portname, QextSerialPort::Polling);
    #endif
    #ifdef Q_WS_MAC
            port = new QextSerialPort(portname, QextSerialPort::Polling);
    #endif
    #ifdef Q_WS_WIN
            port = new QextSerialPort(portname, QextSerialPort::Polling);
    #endif

    port->setBaudRate(BAUD9600);
    port->setFlowControl(FLOW_OFF);
    port->setParity(PAR_NONE);
    port->setDataBits(DATA_8);
    port->setStopBits(STOP_2);
    port->setTimeout(500);

    port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
    qDebug("LOG: Serial port is open: %d", port->isOpen());
}

void RadioController::Close() {
    port->close();
    qDebug("LOG: Serial port is open: %d", port->isOpen());
}

void RadioController::Write(QString data) {
    int i = port->write(data.toAscii(), data.length());
    qDebug("LOG: Wrote serial data: %d", i);
}

QString RadioController::Read() {

    char buff[1024];
    int numBytes;

    numBytes = port->bytesAvailable();
    if(numBytes > 1024) { numBytes = 1024; }

    int i = port->read(buff, numBytes);
    if (i != -1) {
            buff[i] = '\0';
    } else {
            buff[0] = '\0';
    }

    qDebug("LOG: Bytes Available: %d", numBytes);
    qDebug("LOG: Received serial data: %d", i);
    QString out = QString(buff);
    return out;
}

void RadioController::setPower(bool state) {
    if(state) {
        QString data = POWER_ON""CL""NO_AUTOUP""CL;
        qDebug("LOG: Power turned ON!");
        qDebug() << "Data: " << data;
        this->Write(data);
    } else {
        QString data = POWER_OFF""CL;
        qDebug("LOG: Power turned OFF!");
        this->Write(data);
    }
}

bool RadioController::getPower() {
    if(!this->IsRadioConnected()) { return false; }
    QString data = GET_POWER""CL;
    this->Write(data);
    QString reply1 = this->Read();
    qDebug() << "LOG: getPower initial reply: " << reply1;
    this->Write(data);
    QString reply2 = this->Read();
    qDebug() << "LOG: getPower final reply: " << reply2;
    if(reply2.contains(POWER_ON)) { return true; } else { return false; }
}

bool RadioController::IsRadioConnected() {
    QString data = GET_POWER""CL;
    this->Write(data);
    QString reply1 = this->Read();
    qDebug() << "LOG: IsRadioConnected initial reply: " << reply1;
    this->Write(data);
    QString reply2 = this->Read();
    qDebug() << "LOG: IsRadioConnected final reply: " << reply2;
    if(reply2.contains(POWER_ON) || reply2.contains(POWER_OFF)) {
        return true;
    } else {
        qDebug() << "LOG: Radio IS NOT connected!";
        return false;
    }
}

bool RadioController::setFreqModeFilter(QString freq, QString mode, QString filter) {
    qDebug() << "LOG: Freq string raw = " << freq;
    if(freq.startsWith(".")) { freq.prepend("0"); }
    if(freq.endsWith(".")) { freq.append("0"); }
    if(!freq.contains(".")) { freq.append(".0"); }
    QStringList sfreq = freq.split(".", QString::KeepEmptyParts);
    if(sfreq.count() > 2) { QMessageBox::warning(0, MB_InvalidFreq_T, MB_InvalidFreq_B, QMessageBox::Ok); return false; }
    if(sfreq.value(0).length() > 4) { QMessageBox::warning(0, MB_InvalidFreq_T, MB_InvalidFreq_B, QMessageBox::Ok); return false; }
    if(sfreq.value(1).length() > 6) { QMessageBox::warning(0, MB_InvalidFreq_T, MB_InvalidFreq_B, QMessageBox::Ok); return false; }
    QString GMMM = "0000" + sfreq[0];
    QString KKKHHH = sfreq[1] + "000000";
    qDebug() << "LOG: Freq GMMM raw = " << GMMM;
    qDebug() << "LOG: Freq KKKHHH raw = " << KKKHHH;
    GMMM = GMMM.remove(0, GMMM.length() - 4);
    KKKHHH.chop(KKKHHH.length() - 6);
    qDebug() << "LOG: Freq GMMM trimmed = " << GMMM;
    qDebug() << "LOG: Freq KKKHHH trimmed = " << KKKHHH;
    QString cmd = FREQ_HEAD"" + GMMM + KKKHHH + COM.ModeValues[mode] + COM.FilterValues[filter] + ""FREQ_TAIL""CL;
    qDebug() << "LOG: setFreqModeFilter generated command = " << cmd;
    this->curFreq = sfreq[0] + "." + KKKHHH;
    qDebug() << "LOG: RC.curFreq = " << this->curFreq;
    this->Write(cmd);
    return true;
}

void RadioController::setVolume(int val) {
    if(val < 0 || val > 255) { return; }
    QString hexstr;
    hexstr.setNum(val,16);
    qDebug() << "LOG: setVolume int/hex values = " << val << " / " << hexstr;
    QString cmd = VOL"" + hexstr + ""CL;
    this->Write(cmd);
}

void RadioController::setSquelch(int val) {
    if(val < 0 || val > 255) { return; }
    QString hexstr;
    hexstr.setNum(val,16);
    qDebug() << "LOG: setSquelch int/hex values = " << val << " / " << hexstr;
    QString cmd = SQU"" + hexstr + ""CL;
    this->Write(cmd);
}

void RadioController::setIFShift(int val) {
    if(val < 0 || val > 255) { return; }
    QString hexstr;
    hexstr.setNum(val,16);
    qDebug() << "LOG: setIFShift int/hex values = " << val << " / " << hexstr;
    QString cmd = IFSHIFT"" + hexstr + ""CL;
    this->Write(cmd);
}

void RadioController::setAGC(bool val) {
    if(val) {
        QString cmd = AGC_ON""CL;
        this->Write(cmd);
        qDebug() << "LOG: AGC ON";
        return;
    } else {
        QString cmd = AGC_OFF""CL;
        this->Write(cmd);
        qDebug() << "LOG: AGC OFF";
        return;
    }
}

void RadioController::setVSC(bool val) {
    if(val) {
        QString cmd = VSC_ON""CL;
        this->Write(cmd);
        qDebug() << "LOG: VSC ON";
        return;
    } else {
        QString cmd = VSC_OFF""CL;
        this->Write(cmd);
        qDebug() << "LOG: VSC OFF";
        return;
    }
}

void RadioController::setNoiseBlanking(bool val) {
    if(val) {
        QString cmd = NB_ON""CL;
        this->Write(cmd);
        qDebug() << "LOG: NB ON";
        return;
    } else {
        QString cmd = NB_OFF""CL;
        this->Write(cmd);
        qDebug() << "LOG: NB OFF";
        return;
    }
}

void RadioController::setAtten(bool val) {
        if(val) {
             QString cmd = ATT_ON""CL;
             this->Write(cmd);
             qDebug() << "LOG: ATT ON";
             return;
         } else {
             QString cmd = ATT_OFF""CL;
             this->Write(cmd);
             qDebug() << "LOG: ATT OFF";
             return;
         }
}

QString RadioController::getSignal() {
    this->Write(GET_SIG_STREN""CL);
    QString out = this->Read();
    qDebug() << "LOG: getSignal read output = " << out;
    QStringList replies = out.split(CL,QString::KeepEmptyParts);
    foreach(QString reply, replies) {
        if(reply.startsWith("I1",Qt::CaseInsensitive)) {
            QString value = reply.remove("I1");
            bool ok;
            uint hexval = value.toUInt(&ok,16);
            if(ok) {
                return QString::number(hexval);
            }
        }
    }
    return "0";
}
